package fons.navigator.views.river;

import java.awt.BasicStroke;
import java.awt.Stroke;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.util.List;

import com.google.common.collect.Lists;

import edu.umd.cs.piccolo.PNode;
import edu.umd.cs.piccolo.nodes.PPath;
import edu.umd.cs.piccolo.nodes.PText;
import edu.umd.cs.piccolox.util.PFixedWidthStroke;
import fons.model.ontology.Dimension;

public class AlignmentGrid extends PNode {
	private static final long serialVersionUID = 1L;

	private final static Stroke GRID_STROKE = 
			new PFixedWidthStroke(1.0f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_BEVEL, 10.0f,
								  new float[] { 5.0f, 5.0f }, 1.0f);
	
	private List<Dimension> valueDimensions;
	private final List<PPath> paths = Lists.newArrayList();
	private final List<PText> texts = Lists.newArrayList();
	private float valueSpacing;
	private double min;
	private double max;
	private double scale = 1;
		
	public AlignmentGrid (List<Dimension> valueDimensions) {
		this.setValueDimensions(valueDimensions);
	}
	
	private void setValueDimensions (List<Dimension> valueDimensions) {
		this.valueDimensions = valueDimensions;

		paths.clear();
		for (@SuppressWarnings("unused") Dimension d: valueDimensions) {
			final PPath path = new PPath();
			path.setStroke(GRID_STROKE);
			paths.add(path);
		}
	}
		
	public void setValueSpacing (float valueSpacing) {
		this.valueSpacing = valueSpacing;
	}
	
	public float getValueSpacing () {
		return this.valueSpacing;
	}
	
	public void redraw () {
		this.removeAllChildren();
		
		if (max == min) return;
		
		if (max < min) {
			double tmp = max;
			max = min;
			min = tmp;
		}
		
		double xOffset = 1;
		int counter = 0;
		texts.clear();
		
		/*if (reversed) {
			Collections.sort(dims, Ordering.explicit(dims).reverse());	
		}*/
		
		for (final Dimension dim: this.valueDimensions) {
			final PPath path = paths.get(counter);
			final PText text = new PText(dim.getName());
						
			path.setPathTo(new Line2D.Double(new Point2D.Double(xOffset, min), new Point2D.Double(xOffset, max)));
			text.setScale(scale);
			text.setOffset(xOffset - text.getWidth()*scale/2, max + text.getHeight()*scale/2);
			
			this.addChild(path);
			this.addChild(text);
			
			texts.add(text);
			xOffset += valueSpacing;
			counter++;
		}
	}
	
	public void setMin (double min) {
		this.min = min;
	}
	
	public void setMax (double max) {
		this.max = max;
	}

	public void updateLegend(double scale) {
		this.scale = scale;
	}
	
}
